ci: install Playwright's headless shell, not the whole of chromium - #471
Merged
Conversation
This was referenced Aug 17, 2026
lens0021
force-pushed
the
claude/smoke-headless-shell
branch
from
August 19, 2026 04:23
c7643e4 to
358af35
Compare
`playwright install chromium` fetches Chrome for Testing (379 MiB unpacked) and the headless shell (262 MiB) and ffmpeg (5 MiB). These specs run headless and record no video, so the shell is the one Playwright starts and the browser beside it is downloaded to be ignored. Asking for it by name skips it. ffmpeg arrives either way. That is 33s of the smoke job, and roughly three fifths of the bytes in it. Checked rather than reasoned: installed the shell alone into a browser directory of its own, pointed PLAYWRIGHT_BROWSERS_PATH at it so nothing else could be found, and ran the suite against a real bake. 57 passed in 14.6s. --with-deps stays. What it installs is system libraries, which the shell needs as much as the full browser. The alternative was caching ~/.cache/ms-playwright, which the issue suggested. zizmor refuses it: actions/cache in a job that also runs docker/build-push-action is its cache-poisoning audit, high severity, and the comment two lines below this one already records the same objection to setup-node's caching. Fetching less needs no exception. Refs #461. --- _Generated by [Claude Code](https://claude.ai/code/session_935f02d1)_ Co-authored-by: Claude <noreply@anthropic.com>
lens0021
added a commit
that referenced
this pull request
Aug 19, 2026
…470) > Stacked on #469. Review the top commit; the base merges first. The reproducibility check bakes the docs site a second time and diffs it, and the two bakes were 209s of the smoke job's 321s. They are independent by construction, so they can run together. The reason it pays is that a bake is mostly one process. Only the skin passes run beside each other, and even those are three on a four-core runner, so a second bake fills cores the first leaves idle rather than taking any from it. ## Measured Two containers pinned to four cores, the runner's count, on an image built from this PR's base: | | wall clock | |---|---| | one bake alone | 118s | | two, one after the other | 257s | | **two at once, four cores between them** | **150s** | | two at once, two cores each | 166s | 150s is what landed: no cpu flags, both bakes left to size themselves as they do today. Capping each at two cores is slower, because that also halves the concurrency of the part which does parallelise. An earlier run of this benchmark gave the concurrent case a spurious win by capping each container at four cores on a fourteen-core host. That is eight cores between them, and not a runner at all. Discarded. Peak combined resident memory was 1 GiB against the runner's 16, with no OOM in either log. That was the risk worth measuring: two bakes at three skin passes each is six MediaWiki boots at once. Output is byte-identical in every configuration above, which is the check itself agreeing. ## The step's own shell Each bake writes to its own log, because two live logs interleave into neither, and both are printed afterwards in collapsed groups. Verified that a failure still fails the step: a bake pointed at a source directory that does not exist ends it non-zero, and the success path ends it zero. Ran the step's shell verbatim, not a paraphrase of it. The source mount is read-only now that two containers share it, so neither can alter what the other is reading. Only `wikven translate` writes into src, and this is not that. Refs #461. ## On the nine minutes in the issue Worth recording, since it changes what is left to do. #461 measured 535s wall clock on #458, dominated by `binary` at 467s. But `binary` is path-filtered and does not run on a pull request that only touches PHP. On #466, which did exactly that, all 21 checks started within two seconds of each other and `smoke` at 317s was the longest: ``` 317s smoke 186s coverage 145s phan (master) 52s phpunit (REL1_46) 43s docker-image ``` So a PHP-only pull request already goes green in about five and a half minutes, and `smoke` is the whole of its critical path. The nine minutes belongs to image-touching pull requests, where `binary` is the long pole and a separate question. This PR and #471 take `smoke` after the two of them from 321s to roughly 190s. Co-authored-by: Claude <noreply@anthropic.com>
lens0021
force-pushed
the
claude/smoke-headless-shell
branch
from
August 19, 2026 04:29
358af35 to
dd9f30f
Compare
--with-deps is an apt call, and it has hung the smoke job twice in thirteen hours. Both times azure.archive.ubuntu.com -- the mirror a runner on Azure is meant to use -- answered nothing at all, apt fell back to archive.ubuntu.com, took the four InRelease files and then went quiet on the package indexes until the job was killed. Six hours the first time, and thirty minutes the second, which is only because the timeout landed between them. Nothing here needed that call. The runner image carries Google Chrome, Chromium, Edge and Firefox as installed packages, so the shared libraries the headless shell wants are on the machine before we ask for anything. What --with-deps bought was a dependency on a mirror we do not otherwise touch. If the image ever stops shipping them, Playwright names the .so it cannot find, the same way it names an executable it cannot find, so this cannot quietly test the wrong thing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uv1RzRurUH6wrgV5E9PESQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
playwright install chromiumfetches three things: Chrome for Testing (379 MiB unpacked), the headless shell (262 MiB) and ffmpeg (5 MiB). These specs run headless and record no video, so the shell is the one Playwright starts and the browser beside it is downloaded to be ignored. Asking for the shell by name skips it. ffmpeg arrives either way, so what this saves is the 379 MiB, about three fifths of the bytes in a 33s step.Checked, not reasoned
Installed the shell alone into a browser directory of its own, pointed
PLAYWRIGHT_BROWSERS_PATHat it so Playwright could find nothing else, and ran the suite against a real bake:--with-depsstays. What it installs is system libraries, which the shell needs as much as the full browser.If the shell were ever not enough -- a spec asking for a headed browser, or for video -- Playwright fails naming the executable it cannot find, so this cannot quietly test the wrong thing.
Why not cache the browsers, as #461 suggested
zizmor refuses it.
actions/cachein a job that also runsdocker/build-push-actionis its cache-poisoning audit, high severity:Tried it first and read that, which is the same objection the comment two lines below this change already records about setup-node's caching. Fetching less needs no exception.
Refs #461.